package com.fcat.springboot.mqtt.emqx;

import com.fcat.base.common.util.ExceptionUtils;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

@Component
@Configuration
@ConfigurationProperties(MqttConfiguration.PREFIX)
public class MqttConfiguration {

    private static final Logger logger = LoggerFactory.getLogger(MqttConfiguration.class);
    @Autowired
    private MqttPushClient mqttPushClient;

    public static final String PREFIX = "mqtt";
    private String host;
    private String username;
    private String password;
    private int timeout;
    private int keepalive;
    private String clientid;
    private String topic;

    public String getClientid() {
        return clientid;
    }

    public void setClientid(String clientid) {
        this.clientid = clientid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getTopic() {
        return topic;
    }

    public void setTopic(String topic) {
        this.topic = topic;
    }

    public int getTimeout() {
        return timeout;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    public int getKeepalive() {
        return keepalive;
    }

    public void setKeepalive(int keepalive) {
        this.keepalive = keepalive;
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    /**
     * 启动应用，会执行
     * @return
     */
    @Bean
    public MqttPushClient getMqttPushClient(){
        start();
        return mqttPushClient;
    }

    Thread thread;
    private Boolean  isRuning = false;
    /**
     * 启动连接失败或者连接丢失后，会执行start方法，一直重连emqx
     */
    public synchronized void start(){
        logger.info("start");
        if(thread==null || !thread.isAlive() || thread.isInterrupted()){
            thread = new Thread(() -> {
                while (!isRuning) {
                    isRuning = true;
                    logger.info("尝试连接emqx");
                    if(MqttPushClient.client!=null && MqttPushClient.client.isConnected()){
                        logger.info(" MqttPushClient.client已经存在，客户端重连");
                        try {
                            MqttPushClient.client.reconnect();
                            logger.info("重连成功");
                            String mqttTopic[] = topic.split(",");
                            for(int i=0; i<mqttTopic.length; i++){
                                mqttPushClient.subscribe(mqttTopic[i]);//订阅主题
                                logger.info("成功订阅："+mqttTopic[i]);
                            }
                            break;
                        } catch (MqttException e) {
                            logger.info("尝试连接emqx 异常："+ ExceptionUtils.getExceptionMessage(e));
                        }
                    }
                    while(true){
                        if(MqttPushClient.client!=null){
                            try {
                                MqttPushClient.client.close();
                            } catch (MqttException e) {
                                logger.info("关闭失败："+ExceptionUtils.getExceptionMessage(e));
                            }
                        }
                        boolean f = mqttPushClient.connect(host, clientid, username, password, timeout,keepalive);
                        if(f){
                            try {
                                String mqttTopic[] = topic.split(",");
                                for(int i=0; i<mqttTopic.length; i++){
                                    try{
                                        mqttPushClient.getClient().unsubscribe(mqttTopic[i]);//取消订阅主题
                                    }catch (Exception e){
                                        logger.info("取消订阅失败   "+e.getMessage());
                                    }
                                }
                                for(int i=0; i<mqttTopic.length; i++){
                                    mqttPushClient.subscribe(mqttTopic[i]);//订阅主题
                                }
                                logger.info("成功订阅");
                                break;
                            } catch (MqttException e) {
                                logger.info("订阅失败");
                            }
                        }

                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e1) {
                            e1.printStackTrace();
                        }
                    }
                }
                isRuning = false;
            });
        }
        thread.start();

    }
}